function [RX_Output_Frames,fadingSymbols] = Offset_EstimationAndEqualization(RX_IN_Filtered,Mini_Probes_Sign,First_Sym_Index,First_Sample_Index,Oversample,Delay_Samples,N_Frames,Rate,Interleaver_L,Symbol_Rate,Sampling_Frequency,EsNoRatio,effectiveFading,equalizerOffset)

%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%*--------------------------- OFFSET ESTIAMTION AND EQUALIZATION ----------------------------------%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
% [RX_Input_Frames] =
% Offset_EstimationAndEqualization(RX_IN_Filtered,First_Sym_Index,First_Sample_Index,Oversample,Delay_Samples,N_Frames,Rate,Interleaver_L,Symbol_Rate,Sampling_Frequency)
% INPUTS:
% -------
% RX_IN_Filtered : the received signal with errors (vector)
% First_Sym_Index : index of the first symbol in the data frame
% First_Sample_Index : index of the first sample in the data frame
% Oversample : Oversample
% Delay_Samples : margin of samples to be captured befor the start of the
% miniprobe to ensure the existance of the peak
% N_Frames, Rate, Interleaver_L, Symbol_Rate, Sampling_Frequency.
%
% OUTPUTS:
% --------
% RX_Input_Frames : the output is a matrix of all frames (data frames) to
% be input to the receiver basic functions
% this function calls the following functions:
% Channel_Estimation : function used in the sampling error detection
% weighted_smoothing_Window : to smmoth the currently estimated value of
% the carrier offset with previous estimations
% CarrierOffset_Estimation : the function that estimates the carrier
% frequency offset
%
%*-----------------------------------------------------------------------------------------------*%

%*--------------------------------- INITIALIZATIONS ----------------------------------------------%

% Frequency offset initializations
min_step = 1;    %sliding window length
avg_offset = [0 0 0 0]; %vector of the estimated offset
offset_vec_smoothed = avg_offset;   %vector of the smoothed estimated offset

Sym_Index = First_Sym_Index;    %index of the first symbol of each frame
start = First_Sample_Index ;    %index of the first sample of each frame (change each extraction (frame or miniprobe or reinserted oreamble))
Reinserted_Preamble_Index = 1;
Mini_Probes_Index = 1;
numData_Training = (256+31);
fadingLength = numData_Training*Oversample;
%*-----------------------------------------------------------------------------------------------*%

%*------------------------------ FOR THE FIRST ITERATION -----------------------------------------%

%*MINIPROBES ESTIMATION
%*---------------------
%IN Samples
%-----------
%Mini_Probes_Samples : Mini_Probes in samples.
Mini_Probes_Samples(Mini_Probes_Index,:) = RX_IN_Filtered(start-31*Oversample-Delay_Samples:start-1+Delay_Samples);
%Modified_Mini_Probes_Samples : after deleting the signs (used for sampling offset estimation).
Modified_Mini_Probes_Samples(Mini_Probes_Index,:) = Mini_Probes_Sign(mod(Mini_Probes_Index-1,72)+1)*Mini_Probes_Samples(Mini_Probes_Index,:);
%IN Symbols
%-----------
Modified_Mini_Probes(Mini_Probes_Index,:) = Modified_Mini_Probes_Samples(Mini_Probes_Index,Delay_Samples+1:Oversample:end-Delay_Samples);
Mini_Probes_Index = Mini_Probes_Index+1;

%*------------------------------- CHANNEL ESTIMATION ---------------------------------------------%
% the following for estimate the channel and the correct sample for the
% current miniprobe (h: the value of the peak  -  flag: the index change of the peak)
% [h(1) flag(1)] = Channel_Estimation(Modified_Mini_Probes_Samples(1,:),Delay_Samples,Oversample);
% start = start ;%+ flag(1);

%*----------------------- FRAME EXTRACTION AND EQUALIZATION --------------------------------------%
RX_Input_Frames(1,:) = RX_IN_Filtered(start:start+256*Oversample-1);
% the following line to equalize the first data frame, based on the
% estimated channel
%*-----------------------------------------------------------------------------------------------*%


%*------------------------------ FOR THE REMAINING ITERATIONS ------------------------------------%

for frame_index =2 :N_Frames
    %*--------------------- FREQUENCY OFFSET CORRECTION FOR THE PREVIOUS FRAME -------------------%
    % the following for correcting the frequency offset for the current frame
    % RX_Input_Frames: vector for the data frames
    RX_Input_Frames(frame_index-1,:) = RX_Input_Frames(frame_index-1,:).*exp(1*1i*2*pi*offset_vec_smoothed(frame_index-1)*(start+(0:256*Oversample-1))/Sampling_Frequency);
    %*-------------------------------------------------------------------------------------------*%

    %*-------------------------- EXTRACT THE MINIPROBES & REINSERTED PREAMBLES -------------------%
    if mod(frame_index-1,72) == 0 % Extract the reinserted preamble (also it contains a miniprobes)
        start = start + (256 + 103)*Oversample;
        Reinserted_Preamble(Reinserted_Preamble_Index,:) = RX_IN_Filtered(start-103*Oversample:start-1);
        Reinserted_Preamble_Index = Reinserted_Preamble_Index+1;

        %---------------------------------- Miniprobes in Samples --------------------------------%
        Mini_Probes_Samples(Mini_Probes_Index,:) = RX_IN_Filtered(start-31*Oversample-Delay_Samples:start-1+Delay_Samples);
        Modified_Mini_Probes_Samples(Mini_Probes_Index,:) = Mini_Probes_Sign(mod(Mini_Probes_Index-1,72)+1)*Mini_Probes_Samples(Mini_Probes_Index,:);
        Data_After = RX_IN_Filtered(start-103*Oversample-Delay_Samples:start-1+Delay_Samples-103*Oversample+31*Oversample);
        
        %IN Symbols
        %-----------
        Modified_Mini_Probes(Mini_Probes_Index,:) = Modified_Mini_Probes_Samples(Mini_Probes_Index,Delay_Samples+1:Oversample:end-Delay_Samples);
        %-----------------------------------------------------------------------------------------%
        Mini_Probes_Index = Mini_Probes_Index+1;

    else           % Extract the miniprobe
        start = start + (256 + 31)*Oversample ;
        %------------------------------------- for Samples --------------------------------------%
        Mini_Probes_Samples(Mini_Probes_Index,:) = RX_IN_Filtered(start-31*Oversample-Delay_Samples:start-1+Delay_Samples);
        Modified_Mini_Probes_Samples(Mini_Probes_Index,:) = Mini_Probes_Sign(mod(Mini_Probes_Index-1,72)+1)*Mini_Probes_Samples(Mini_Probes_Index,:);
        Data_After = RX_IN_Filtered(start-31*Oversample-Delay_Samples:start-1+Delay_Samples);
        
        %IN Symbols
        %-----------
        Modified_Mini_Probes(Mini_Probes_Index,:) = Modified_Mini_Probes_Samples(Mini_Probes_Index,Delay_Samples+1:Oversample:end-Delay_Samples);
        %----------------------------------------------------------------------------------------%
        Mini_Probes_Index = Mini_Probes_Index+1;

    end
    %*-------------------------------------------------------------------------------------------*%

    %*------------------------- FREQUENCY OFFSET CORRECTION FOR THE MINIPROBES -------------------%
    MiniProbe_FirstSample_Index = start-31*Oversample-Delay_Samples;    % the first sample in the current miniprobe
    MiniProbe_Samples_Length = 31*Oversample+2*Delay_Samples; % normal length + delay length

    % the following for correcting the frequency offset for the current miniprobe
    Modified_Mini_Probes_Samples(frame_index,:) = Modified_Mini_Probes_Samples(frame_index,:).*exp(1*1i*2*pi*offset_vec_smoothed(frame_index-1)*(MiniProbe_FirstSample_Index+(0:MiniProbe_Samples_Length-1))/Sampling_Frequency);
    Mini_Probes_Samples(frame_index,:) = Mini_Probes_Samples(frame_index,:).*exp(1*1i*2*pi*offset_vec_smoothed(frame_index-1)*(MiniProbe_FirstSample_Index+(0:MiniProbe_Samples_Length-1))/Sampling_Frequency);
    %*-------------------------------------------------------------------------------------------*%
    
    %*----------------------- CHANNEL ESTIMATION FROM THE CORRECTED MINIPROBES -------------------%
    % the following line for channel estimation and the correct sample detection
%     [h(frame_index) flag(frame_index)] = Channel_Estimation(Modified_Mini_Probes_Samples(frame_index-0,:),Delay_Samples,Oversample);
%     start = start;% + flag(frame_index);
    %*-------------------------------------------------------------------------------------------*%
    
    %------------------------------------  EQUALIZER ---------------------------------------------%
    % Note that we always equalize the (frame number-1)
    
    % the preceding miniprobe sign
    first_sign = Mini_Probes_Sign(mod(Mini_Probes_Index-3,72)+1);
    
    % the following factor to delete the effect of reinserted preamble to
    % match the current frame to equalize with the correct channel.
    Reinserted_Factor = fix((frame_index-2)/72)*(103-31)*Oversample;
    
    %-Equivalent fadding to that frame
    %---------------------------------
    startSample=(frame_index-2)*fadingLength +1+Reinserted_Factor ;
    endSample=startSample + fadingLength-1 ;
    fadingSamples(frame_index-1,:)=effectiveFading(:,startSample:endSample-31*Oversample);
    averageFading=mean(fadingSamples,2);
    channelFreqDomain(:,frame_index-1)=fft(averageFading, numData_Training);
    channelAbsSquared(:,frame_index-1)=abs(channelFreqDomain(:,frame_index-1)).^2;
    
    % prepare the data for the frame to be equalized
    Current_Frame_toEqualize = RX_Input_Frames(frame_index-1,:);
    Current_Tranining_toEqualize = Mini_Probes_Samples(frame_index-1,Delay_Samples+1:end-Delay_Samples);

    % equalizer function
    RX_Output_Frames(frame_index-1,:) = HF_Simple_SignleTapEqualizer(Current_Frame_toEqualize,fadingSamples(frame_index-1,:),Oversample,EsNoRatio,equalizerOffset);
%     RX_Output_Frames(frame_index-1,:) = HF_FreqD_EQUALIZE(Current_Tranining_toEqualize,Current_Frame_toEqualize,Data_After,Oversample,first_sign,EsNoRatio,channelFreqDomain(:,frame_index-1),channelAbsSquared(:,frame_index-1),equalizerOffset);
   
    % prepare the data for the next frame
    if mod(frame_index-1,72) == 0
        Data_Before = Reinserted_Preamble(Reinserted_Preamble_Index-1,1:end-31*Oversample);
    else
        Data_Before = Current_Frame_toEqualize;
    end
    %*-------------------------------------------------------------------------------------------*%
    
    %*-------------------------- FRAME EXTRACTION AND CHANNEL EQUALIZATION -----------------------%
    % extracting the current frame (after knowing the correct sample index)
    RX_Input_Frames(frame_index,:) = RX_IN_Filtered(start:start+256*Oversample-1);
    %*-------------------------------------------------------------------------------------------*%
    
    %*----------------------------- FREQUENCY OFFSET ESTIMATION ----------------------------------%
    % Carrier frequency offset estimatiom from the current estimated
    % miniprobe and the one lag it by minstep frames.
    if frame_index > min_step
        freq_offset_estimated(frame_index) = CarrierOffset_Estimation (Modified_Mini_Probes,frame_index,min_step,Symbol_Rate); %#ok, the offset estimated at this frame index during one symbol
        offset_vec_smoothed(frame_index) = weighted_smoothing_Window(freq_offset_estimated(min_step:end)); %#ok, the smoothed offset
    end
    %---------------------------------------------------------------------------------------------%
    % calculate the index of the start symbol for the following frame
    Sym_Index = Sym_Index + 256 + 31;
    if (0 == mod(frame_index-1,72))
        Sym_Index = Sym_Index + 72;
    end
    %*-------------------------------------------------------------------------------------------*%
end
%*-----------------------------------------------------------------------------------------------*%


%*---------------------------------------- LAST FRAME --------------------------------------------%
% the frequency offset correction for the last data frame
%*-------------------------------------------------------
RX_Input_Frames(N_Frames,:) = RX_Input_Frames(N_Frames,:).*exp(1*1i*2*pi*offset_vec_smoothed(N_Frames)*(Sym_Index*Oversample+(0:256*Oversample-1))/Sampling_Frequency);

% Extract the miniprobe
%*----------------------
start = start + (256 + 31)*Oversample ;
Mini_Probes_Samples(Mini_Probes_Index,:) = RX_IN_Filtered(start-31*Oversample-Delay_Samples:start-1+Delay_Samples);
%*-----------------------------------------------------------------------------------------------*%

%------------------------------------------ EQUALIZER --------------------------------------------%
% the preceding miniprobe sign
first_sign = Mini_Probes_Sign(mod(Mini_Probes_Index-2,72)+1);

%-Equivalent fadding to that frame
Reinserted_Factor = fix((N_Frames-1)/72)*(103-31);
startSample=(N_Frames-1)*fadingLength +1+Reinserted_Factor ;
endSample=startSample + fadingLength-1 ;
fadingSamples(N_Frames,:)=effectiveFading(:,startSample:endSample-31*Oversample);
averageFading=mean(fadingSamples,2);
channelFreqDomain(:,N_Frames)=fft(averageFading, numData_Training);
channelAbsSquared(:,N_Frames)=abs(channelFreqDomain(:,N_Frames)).^2;

% prepare the data for the frame to be equalized
Current_Frame_toEqualize = RX_Input_Frames(N_Frames,:);
Current_Tranining_toEqualize = Mini_Probes_Samples(N_Frames,Delay_Samples+1:end-Delay_Samples);
Data_After = Mini_Probes_Samples(N_Frames+1,Delay_Samples+1:end-Delay_Samples);

% equalizer function
RX_Output_Frames(N_Frames,:) = HF_Simple_SignleTapEqualizer(Current_Frame_toEqualize,fadingSamples(N_Frames,:),Oversample,EsNoRatio,equalizerOffset);
% RX_Output_Frames(N_Frames,:) = HF_FreqD_EQUALIZE(Current_Tranining_toEqualize,Current_Frame_toEqualize,Data_After,Oversample,first_sign,EsNoRatio,channelFreqDomain(:,N_Frames),channelAbsSquared(:,N_Frames),equalizerOffset);
%*-------------------------------------------------------------------------------------------*%
fadingSymbols = fadingSamples(:,1:Oversample:end);